using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using Phydeaux.Utilities;

namespace BTreeSharp
{
    class BuiltInAccessor<T>:IAccessor
    {
        List<Func<T, object>> getters = new List<Func<T, object>>();
        List<Proc<T, object>> setters = new List<Proc<T, object>>();
        List<Type> types = new List<Type>();
        private BuiltInAccessor()
        { }

        static public IAccessor Create(List<PropertyInfo> props)
        {
            BuiltInAccessor<T> accessor = new BuiltInAccessor<T>();
            props.Sort(new Comparison<PropertyInfo>(delegate(PropertyInfo p1, PropertyInfo p2)
                                                    {
                                                        return p1.Name.CompareTo(p2.Name);
                                                    }));
            foreach (PropertyInfo pi in props)
            {
                accessor.getters.Add(Dynamic<T>.Instance.Property<object>.Explicit.Getter.CreateDelegate(pi));
                accessor.setters.Add(Dynamic<T>.Instance.Property<object>.Explicit.Setter.CreateDelegate(pi));
                accessor.types.Add(pi.PropertyType);
            }
            return accessor;
        }
        #region IAccessor Members

        public object[] ReadValues(object instance)
        {
            object[] values = new object[getters.Count];
            int i=0;
            foreach (Func<T, object> getter in getters)
                values[i++] = getter((T)instance);
            return values;
        }
        public Type[] Types
        {
            get { return types.ToArray();}
        }
        public void SetValues(object instance, object[] values)
        {
            int i = 0;
            foreach (Proc<T, object> setter in setters)
                  setter((T)instance,values[i++]);
        }

        #endregion
    }
}
